package cn.edu.cumt.ec.shop.controller;

import cn.edu.cumt.ec.shop.dto.UpdatePwdDto;
import cn.edu.cumt.ec.shop.entity.User;
import cn.edu.cumt.ec.shop.exception.CustomException;
import cn.edu.cumt.ec.shop.exception.ErrorCode;
import cn.edu.cumt.ec.shop.dto.UserLoginDTO;
import cn.edu.cumt.ec.shop.security.JwtUser;
import cn.edu.cumt.ec.shop.security.ResponseUserToken;
import cn.edu.cumt.ec.shop.service.AuthService;
import cn.edu.cumt.ec.shop.util.RedisUtil;
import cn.edu.cumt.ec.shop.util.SecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;


@RestController
@Api(value = "登陆注册及刷新token",tags = "登录相关接口")
@RequestMapping("/auth")
public class AuthController {
    @Value("${jwt.header}")
    private String tokenHeader;

    private final AuthService authService;

    private final RedisUtil redisUtil;

    @Autowired
    public AuthController(AuthService authService,RedisUtil redisUtil) {
        this.authService = authService;
        this.redisUtil = redisUtil;
    }

    @PostMapping(value = "/login")
    @ApiOperation(value = "登陆", notes = "登陆成功返回token,登陆之前请先注册账号")
    public ResponseUserToken login(
            @Valid @RequestBody UserLoginDTO userLoginParam) {
        final ResponseUserToken responseUserToken = authService.login(userLoginParam.getPhoneNumber(), userLoginParam.getPwd());
        return responseUserToken;
    }

    @GetMapping(value = "/logout")
    @ApiOperation(value = "登出", notes = "退出登陆")
    @ApiImplicitParams({@ApiImplicitParam(name = "Authorization", value = "Authorization token", required = true, dataType = "string", paramType = "header")})
    public String logout(HttpServletRequest request) {
        String token = request.getHeader(tokenHeader);
        if (token == null) {
            throw new CustomException(ErrorCode.JSON_PARSE_ERROR);//未授权
        }
        authService.logout(token);
        return "logout success";
    }

    @GetMapping(value = "/user")
    @ApiOperation(value = "根据token获取用户信息", notes = "根据token获取用户信息")
    @ApiImplicitParams({@ApiImplicitParam(name = "Authorization", value = "Authorization token", required = true, dataType = "string", paramType = "header")})
    public JwtUser getUser(HttpServletRequest request) {
        String token = request.getHeader(tokenHeader);
        if (token == null) {
            throw new CustomException(ErrorCode.JSON_PARSE_ERROR);//未授权
        }
        JwtUser jwtUser = authService.getUserByToken(token);
        return jwtUser;
    }

    @PostMapping(value = "/sign")
    @ApiOperation(value = "用户注册")
    public User sign(@RequestBody User user) {
        if (StringUtils.isAnyBlank(user.getPhoneNumber(), user.getPwd())) {
            throw new CustomException("手机号或者密码不能为空");
        }
        return authService.register(user);
    }


    @ApiOperation(value = "修改密码")
    @PostMapping("/updatePwd")
    public String updatePwd(HttpServletRequest request,@RequestBody UpdatePwdDto dto)
    {
        String newPassword = dto.getNewPassword();
        String oldPassword = dto.getOldPassword();

        String token = request.getHeader(tokenHeader);
        JwtUser jwtUser = authService.getUserByToken(token);

        String phoneNumber = jwtUser.getPhoneNumber();
        JwtUser userInCache = (JwtUser)redisUtil.get(phoneNumber);
        String password = userInCache.getPassword();
        if (!SecurityUtils.matchesPassword(oldPassword, password))
        {
           throw new CustomException("修改密码失败，旧密码错误");
        }
        if (SecurityUtils.matchesPassword(newPassword, password))
        {
            throw new CustomException("新密码不能与旧密码相同");
        }
        if (authService.resetUserPwd(phoneNumber, SecurityUtils.encryptPassword(newPassword)) > 0) {
            return "success";
        }
        throw new CustomException("修改密码异常，请联系管理员");
    }

}
